﻿#include "../../Common/Common.h"

// 1. 首先定义关键的Windows宏，净化windows.h的包含环境
#define WIN32_LEAN_AND_MEAN
#define NOMINMAX
#include <windows.h> // 先包含windows.h，让它在我们设定的规则下展开

// 2. 接下来是关键的一步：防止gl.h内部的重复定义
// 定义OpenGL API调用的宏，确保它们使用stdcall调用约定
// 这通常是gl.h所期望的
#ifndef APIENTRY
#define APIENTRY __stdcall
#endif
#ifndef APIENTRYP
#define APIENTRYP APIENTRY *
#endif
#ifndef GLAPI
#define GLAPI extern
#endif

#include <osgViewer/Viewer>
#include <osgDB/ReadFile>
#include <osgGA/GUIEventAdapter>
#include <osgGA/TrackballManipulator>
#include <osgViewer/ViewerEventHandlers>

#include <iostream>

// 模拟一个事件类，响应单机h
class PrintName : public osgGA::GUIEventHandler
{
public:
	virtual void getUsage(osg::ApplicationUsage& usage) const
	{
		usage.addKeyboardMouseBinding("tommy", "Great.");
	}

	virtual bool handle(osgGA::Event* event, osg::Object* object, osg::NodeVisitor* nv)
	{

		osgGA::GUIEventAdapter* ea = dynamic_cast<osgGA::GUIEventAdapter*>(event);

		if (ea->getHandled()) return false;

		switch (ea->getEventType())
		{
		case(osgGA::GUIEventAdapter::KEYDOWN):
		{
			if (ea->getKey() == 't')
			{
				std::cout << "PrintName handle(): my name is tommy." << std::endl;
			}
			break;
		}
		}
		return true; // 返回true代表这个事件被处理了。可以用ea->getHandled()识别。
	}
};

int main()
{
	std::cout << "main function start." << std::endl;
	osg::ref_ptr<osgViewer::Viewer> viewer = new osgViewer::Viewer;
	osg::ref_ptr<osg::Node> node = new osg::Node;

	// 申请一个定时器类
	osg::Timer* timer = new osg::Timer;
	osg::Timer_t start_frame_time = 0;
	osg::Timer_t end_frame_time = 0;

	// 每帧控制法
	float per_str_time = 0.0;
	float per_end_time = 0.0;

	// 计算帧数
	int counts = 0;
	float sleep_time = 0;
	float last_sleep = 0.0001;

	std::cout << timer->getSecondsPerTick() << std::endl;

	//start_time = timer->tick();
	//// 读取模型
	//node = osgDB::readNodeFile("avatar.osg");
	//end_time = timer->tick();
	//std::cout << "方法1、读取模型事件为：" << timer->delta_s(start_time, end_time) << "s" << std::endl;

	// 读取模型
	timer->setStartTick();
	node = osgDB::readNodeFile("cessna.osg");
	std::cout << "方法2、读取模型事件为：" << timer->time_s() << "s" << std::endl;

	// 读取模型
	//float start = 0.0;
	//float end = 0.0;
	//start = viewer->elapsedTime();
	//node = osgDB::readNodeFile("avatar.osg");
	//end = viewer->elapsedTime();
	//std::cout << "方法3、（可能不够准确）读取模型事件为：" << end - start << "s" << std::endl;

	// 添加帮助事件
	viewer->addEventHandler(new PrintName);
	viewer->addEventHandler(new osgViewer::HelpHandler);
	viewer->addEventHandler(new osgViewer::StatsHandler);	// 显示帧数
	viewer->addEventHandler(new osgViewer::WindowSizeHandler); // 全屏/小窗口，按F切换
	viewer->addEventHandler(new osgViewer::ScreenCaptureHandler); // 截屏
	viewer->addEventHandler(new osgViewer::RecordCameraPathHandler); // 保存相机的操作序列，用于复现

	viewer->setSceneData(node.get());
	// 设置为单屏幕模式
	viewer->setUpViewInWindow(100, 100, 1024, 768); // 在主屏幕上创建窗口

	// 或者使用以下方式
	// viewer.setUpViewOnSingleScreen(0); // 使用第一个屏幕

	viewer->setCameraManipulator(new osgGA::TrackballManipulator);
	// return viewer->run();  // run()函数设置环境变量OSG_RUN_FRAME_COUNT后，到达指定帧数后自动退出。

	while (!viewer->done())
	{

		per_str_time = timer->tick();

		if (counts == 0) 
		{
			start_frame_time = timer->tick();
		}
		counts++;
		viewer->frame();

		per_end_time = timer->tick();

		// 限制帧数为10，每针绘制0.1s
		int target_fps = 35;
		float target_interval = 1.0 / (float)target_fps;
		sleep_time = target_interval - (timer->delta_s(per_str_time, per_end_time) / 3);
		if (sleep_time < 0)
		{
			sleep_time = last_sleep * 0.8;
		}
		last_sleep = sleep_time;
		OpenThreads::Thread::microSleep(sleep_time * 1000000);
		

		if (counts == 3)
		{
			
			counts = 0;
			end_frame_time = timer->tick();
			std::cout << "当前帧率为：" << 3 / (timer->delta_s(start_frame_time, end_frame_time)) << std::endl;
		
			// 得到当前每一帧绘制所用时间
			//sleep_time = 0.1 - (timer->delta_s(start_frame_time, end_frame_time) / 3);
			//if (sleep_time < 0)
			//{
			//	sleep_time = last_sleep * 0.8 ;
			//}
		}

	}

	return 0;
}



